'use strict';

const winston = require('winston');
const DailyRotateFile = require('winston-daily-rotate-file');
const fs = require('fs');
const path = require('path');
const config = require('../config');

const color = {
    red: '\u001B[31m',
    green: '\u001B[32m',
    blue: '\u001B[34m',
    white: '\u001B[37m',
    bgRed: '\u001B[41m',
    bold: '\u001B[1m',
    reset: '\u001B[0m',
    yellow: '\u001B[33m',
};

const alignRight = (str, length) => {
    if (typeof str !== 'string' || typeof length !== 'number') {
        console.warn(`${color.yellow}⚠️ alignRight 参数错误：str 必须是字符串，length 必须是数字${color.reset}`);
        return str;
    }

    const escChar = String.fromCharCode(27);
    const ansiColorRegex = new RegExp(`${escChar}\\[[0-9;]*m`, 'g');
    const pureText = str.replace(ansiColorRegex, '');
    const spaceCount = Math.max(0, length - pureText.length);

    return str + ' '.repeat(spaceCount);
};

// 确保日志目录存在
const logDir = config.logger.dir || './logs';
try {
    if (!fs.existsSync(logDir)) {
        fs.mkdirSync(logDir, { recursive: true });
    }
} catch (error) {
    console.error(`${color.red}❌ 日志目录创建失败：${error.message}${color.reset}`);
}

// 新增：生成请求ID（用于关联同一请求的日志）
const generateRequestId = () => {
    return Math.random().toString(36).substr(2, 10);
};

// 优化日志格式，增加请求ID和完整堆栈
const logFormat = winston.format.combine(
    winston.format.errors({ stack: true }),
    winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
    winston.format.metadata(), // 保留元数据
    winston.format.printf((logObj) => {
        const timestamp = logObj.timestamp || new Date().toLocaleString();
        const level = (logObj.level || 'info').toUpperCase();
        const message = logObj.message || '';
        const stack = logObj.stack || '';
        const requestId = logObj.metadata.requestId || generateRequestId();

        let levelStr, icon, logContent;
        const targetWidth = 9;

        switch (level) {
            case 'ERROR':
                levelStr = alignRight(`${color.bgRed}${color.white}${color.bold}[${level}]${color.reset}`, targetWidth);
                icon = '❌ ';
                logContent = stack
                    ? `${icon}${message}\n${color.red}堆栈信息：${stack}${color.reset}`
                    : `${icon}${message}`;
                break;
            case 'INFO':
                levelStr = alignRight(`${color.green}${color.bold}[${level}]${color.reset}`, targetWidth);
                icon = '✅ ';
                logContent = `${icon}${message}`;
                break;
            case 'DEBUG':
                levelStr = alignRight(`${color.blue}[${level}]${color.reset}`, targetWidth);
                icon = '🔧 ';
                logContent = `${icon}${message}`;
                break;
            default:
                levelStr = alignRight(`[${level}]`, targetWidth);
                icon = '';
                logContent = `${icon}${message}`;
                break;
        }

        return `[${timestamp}] [REQ-${requestId}] ${levelStr}${logContent}`;
    }),
);

const rotateTransport = (level) => {
    return new DailyRotateFile({
        filename: path.resolve(logDir, `${level}-%DATE%.log`),
        level,
        maxSize: config.logger.rotate?.maxSize || '50m',
        maxFiles: config.logger.rotate?.maxFiles || '7d',
        datePattern: config.logger.rotate?.datePattern || 'YYYY-MM-DD',
        zippedArchive: true,
        format: winston.format.combine(
            winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
            winston.format.printf((logObj) => {
                const stack = logObj.stack || '';
                const requestId = logObj.metadata?.requestId || generateRequestId();
                const logContent = stack ? `${logObj.message}\n堆栈信息：${stack}` : logObj.message;
                return `[${logObj.timestamp}] [REQ-${requestId}] [${logObj.level.toUpperCase()}] ${logContent}`;
            }),
        ),
    });
};

const logger = winston.createLogger({
    level: config.logger?.level || 'info',
    format: logFormat,
    transports: [
        new winston.transports.Console({ format: logFormat, stderrLevels: ['error'] }),
        rotateTransport('info'),
        rotateTransport('error'),
    ],
    exceptionHandlers: [
        new winston.transports.Console({ format: logFormat }),
        new DailyRotateFile({ filename: path.resolve(logDir, 'exception-%DATE%.log') }),
    ],
});

// 新增：支持传入请求ID
module.exports = {
    info: (message, metadata = {}) => {
        logger.info(message, { metadata });
    },
    error: (message, metadata = {}) => {
        logger.error(message, { metadata });
    },
    debug: (message, metadata = {}) => {
        logger.debug(message, { metadata });
    },
    color,
    generateRequestId,
    logger,
};
